package com.x25175.file.controller;


import cn.afterturn.easypoi.excel.entity.result.ExcelImportResult;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.x25175.file.Vo.LayuiTableVo;
import com.x25175.file.Vo.Query;
import com.x25175.file.Vo.ResponseVO;
import com.x25175.file.Vo.StudentVo;
import com.x25175.file.constant.ImgPrefix;
import com.x25175.file.entity.Log;
import com.x25175.file.entity.Student;
import com.x25175.file.entity.User;
import com.x25175.file.enums.StartEnum;
import com.x25175.file.service.LogService;
import com.x25175.file.service.StudentService;
import com.x25175.file.util.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;


/**
 * @author 徐佳辉
 * @date 2020/11/19 11:29
 */
@Controller
@Slf4j
@CrossOrigin
public class StudentController {


    @Autowired
    private StudentService studentService;
    @Autowired
    private PictureController pictureController;
    @Autowired
    private LogService logService;
    @Value("${pictureurl}")
    private String url;


    /**
     * layui数据表格
     * 类型默认get
     * 返回分页数据
     *
     * @param page
     * @param limit
     * @return 返回格式 默认
     * {
     * "code":0
     * "msg":""
     * "count":总数
     * "data":[{},{}]
     * }
     */
    @GetMapping("/list")
    @ResponseBody
    public LayuiTableVo list(int page, int limit) {
        PageHelper.startPage(page, limit);
        PageInfo<Student> pageInfo = new PageInfo<>(studentService.selectAll());

        return LayuiTableVo.ok(pageInfo.getList(), (int) pageInfo.getTotal());

    }

    /**
     * 身份证手机脱敏
     * 结果
     * 133****3333
     * 330282*********846
     *
     * @param list
     * @return
     */
    private List<Student> Desensitization(List<Student> list) {
        for (Student student : list) {
            student.setIdCard(IdCardAdd.desensitizedIdNumber(student.getIdCard()));
            student.setPhone(IdCardAdd.Phone(student.getPhone()));
        }
        return list;
    }

    /**
     * 返回没有pic的student
     *
     * @return
     */
    @GetMapping("/listnotpic")
    @ResponseBody
    public ResponseVO listAll() {
        List<Student> studentList = studentService.selectAll();
        List<Student> students = new ArrayList<>();
        for (Student student : studentList) {
            if (StringUtils.isBlank(student.getPicture())) {
                students.add(student);
            }
        }
        return ResponseVO.ok(students);
    }


    /**
     * 精确查询
     *
     * @param page
     * @param limit
     * @param query
     * @return
     */
    @PostMapping("/exactquery")
    @ResponseBody
    public LayuiTableVo exactQuery(int page, int limit, Query query, HttpSession session) {
        log.info("78query:[{}]", query);

        PageHelper.startPage(page, limit);
        Query query1 = queryremoveBlank(query);

        Log(session, query1, 1);

        PageInfo<Student> pageInfo = new PageInfo<>(studentService.selectExact(query1));
        return LayuiTableVo.ok(pageInfo.getList(), (int) pageInfo.getTotal());

    }

    /**
     * 模糊查询
     *
     * @param page
     * @param limit
     * @param query
     * @return
     */
    @PostMapping("/like")
    @ResponseBody
    public LayuiTableVo like(int page, int limit, Query query, HttpSession session) {
        log.info("97query:[{}]", query);
        PageHelper.startPage(page, limit);
        Query query1 = queryremoveBlank(query);
        Log(session, query1, 2);
        PageInfo<Student> pageInfo = new PageInfo<>(studentService.selectLike(query1));
        return LayuiTableVo.ok(pageInfo.getList(), (int) pageInfo.getTotal());

    }

    /**
     * 记录查询
     *
     * @param session
     * @param query1
     * @param queryMethod
     */
    private void Log(HttpSession session, Query query1, Integer queryMethod) {
        User user = (User) session.getAttribute("user");
        Log log = new Log();
        log.setUserId(user.getUserId());
        /**
         * 1为精确 2为模糊
         */
        log.setQueryMethod(queryMethod);
        log.setName(query1.getName());
        log.setPhone(query1.getPhone());
        log.setIdCard(query1.getIdCard());
        log.setMajor(query1.getMajor());
        log.setCreateTime(new Date());
        logService.insert(log);
    }

    private Query queryremoveBlank(Query query) {
        query.setIdCard(StringUtils.isBlank(query.getIdCard()) ? null : query.getIdCard());
        query.setMajor(StringUtils.isBlank(query.getMajor()) ? null : query.getMajor());
        query.setName(StringUtils.isBlank(query.getName()) ? null : query.getName());
        query.setPhone(StringUtils.isBlank(query.getPhone()) ? null : query.getPhone());
        return query;
    }


    /**
     * 导入excel
     *
     * @param file
     * @return
     */
    @PostMapping("/upExcel")
    @ResponseBody
    public ResponseVO upExcel(MultipartFile file) {
        if (file.getOriginalFilename() != null) {
            log.info("fileName:[{}]", file.getOriginalFilename());
        }

        ExcelImportResult<StudentVo> re = null;
        try {
            re = ExcelUtil.importExcel(file, 1, true, StudentVo.class);
        } catch (IOException e) {
            e.printStackTrace();
        }


        List<StudentVo> studentVo = re.getList();
        List<StudentVo> failList = re.getFailList();
        log.info("faillist:{}", failList);
//      log.info("ExcelImportResult:{}", ExcelImportResult);
        String msg = "";
        if (failList.size() > 0) {
            for (StudentVo vo : failList) {
                msg += "\n第" + vo.getRowNum() + "行的错误是：" + vo.getErrorMsg() + "\n";
                log.info("第{}行，{}", vo.getRowNum(), vo.getErrorMsg());
            }
        }


        log.info("StudentVo:[{}]", studentVo);
        //所有的值
        List<Student> studentList = studentService.selectAll();
        //要覆盖更新的值
        List<Student> updateList = new ArrayList<>();
        //循环的索引
        int index = -1;
        //要删除的索引集合
        List<Integer> integerList = new ArrayList<>();

        for (StudentVo vo : studentVo) {
            index++;
            String idCard = vo.getIdCard();
            if (idCard == null) {
                idCard = "";
            }
            String phone = vo.getPhone();
            if (phone == null) {
                phone = "";
            }
            for (Student student : studentList) {
                if (idCard.equals(student.getIdCard()) || phone.equals(student.getPhone())) {
                    //copy忽略null
                    BeanUtils.copyProperties(vo, student, IgnoreNullUtil.getNullPropertyNames(vo));
                    //添加是更新的数据
                    updateList.add(student);
                    //记录要删除的索引
                    integerList.add(index);
                }

            }
        }

        log.info("integerList,{}", integerList);
        //去除重复指
        ListUtil.removeDuplicate(integerList);
        log.info("integerList,{}", integerList);

        //倒序删除是更新的数据
        for (int i = integerList.size() - 1; i >= 0; i--) {

            log.info("integerList.get,{}", integerList.get(i));
            log.info("studentVo.size,{}", studentVo.size());
            studentVo.remove((int) integerList.get(i));
        }


//        List<StudentVo> studentVos = new ArrayList<>();
//        for (Integer integer : integerList) {
//            studentVos.add(studentVo.get((int) integer));
//        }

        //删除重复后的excelvo
        log.info("删除重复后的excelvo student:[{}]", studentVo);
        log.info("删除的索引 integerList:[{}]", integerList);

        //要覆盖的值
        for (Student student : updateList) {
            //这里不建议这样做最好能够dao层批量更新
            studentService.updateDynamic(student);
        }

        //更新新的值
        if (studentVo.size() == 0 || studentVo == null) {
            return ResponseVO.ok("导入成功，重复数据覆盖" + msg);
        }
        boolean b = studentService.saveFromExcel(studentVo);
        return b ? ResponseVO.ok("导入成功" + msg) : ResponseVO.error("导入失败");
    }

    /**
     * 直接全部导出excel
     *
     * @param response
     */
    @GetMapping("/export")
    public void export(HttpServletResponse response) {
        try {
            log.info("导出excel。。。");
            List<Student> students = studentService.selectAll();
            List<StudentVo> studentVos = new ArrayList<>();
            for (Student student : students) {
                StudentVo studentVo = new StudentVo();
                BeanUtils.copyProperties(student, studentVo);
                log.info("studentVo:[{}]", studentVo);
                studentVos.add(studentVo);
            }
            log.info("studentVos:[{}]", studentVos);
            EasyPoiUtil.exportExcel(studentVos, null, null, StudentVo.class, "all.xls", response);
        } catch (Exception e) {
            e.printStackTrace();
            log.error("导出全部错误");

        }


    }

    /**
     * 导出最近的查询结果
     *
     * @param response
     */
    @GetMapping("/exportQuery")
    @ResponseBody
    public ResponseVO exportQuery(HttpServletResponse response) {
        log.info("导出excel。。。");


        List<Student> students;
        List<Log> logs = logService.selectList();
        Log log;
        if (logs.size() == 0) {
            students = studentService.selectAll();
        } else {
            log = logs.get(0);
            if (log.getQueryMethod() == 1) {
                //精确
                Query query = LogValueToQuery(log);
                if (query == null) {
                    students = studentService.selectAll();
                } else {
                    students = studentService.selectExact(query);
                }

            } else {
                //模糊
                Query query = LogValueToQuery(log);
                if (query == null) {
                    students = studentService.selectAll();
                } else {
                    students = studentService.selectLike(query);
                }
            }
        }


        List<StudentVo> studentVos = new ArrayList<>();
        for (Student student : students) {
            StudentVo studentVo = new StudentVo();
            BeanUtils.copyProperties(student, studentVo);
            studentVos.add(studentVo);
        }

        EasyPoiUtil.exportExcel(studentVos, null, null, StudentVo.class, "query.xls", response);
        return ResponseVO.ok();

    }

    /**
     * log中的值赋值给query
     *
     * @param log
     * @return
     */
    private Query LogValueToQuery(Log log) {
        Query query = new Query();
        query.setName(log.getName());
        query.setIdCard(log.getIdCard());
        query.setMajor(log.getMajor());
        query.setPhone(log.getPhone());
        return query;
    }


    /**
     * 选中导出
     *
     * @param studentId
     * @param response
     */
    @GetMapping("/exportSome")
    public void exportSome(String studentId, HttpServletResponse response) {
        try {
            log.info("选中导出students:[{}]", studentId);
            if (studentId.length() == 0 || studentId == null) {
                throw new Exception("没有选中项");

            }
            String[] st = studentId.split(",");
            List<Student> studentList = studentService.selectByStudentIdStringArray(st);
            List<StudentVo> studentVos = new ArrayList<>();
            for (Student student : studentList) {
                StudentVo studentVo = new StudentVo();
                BeanUtils.copyProperties(student, studentVo);
                log.info("studentVo:[{}]", studentVo);
                studentVos.add(studentVo);
            }
            log.info("studentVos:[{}]", studentVos);
            EasyPoiUtil.exportExcel(studentVos, null, null, StudentVo.class, "some.xls", response);
        } catch (Exception e) {
            log.error("选中导出错误:[{}]",e.getMessage());
        }
    }


    /**
     * 添加
     *
     * @param studentVo
     * @return
     */
    @PostMapping("/stuinsert")
    @ResponseBody
    public ResponseVO insert(StudentVo studentVo) {
//        考虑添加默认未报名状态
        Student student = new Student();
        BeanUtils.copyProperties(studentVo, student);
        student.setStart(StartEnum.YES.getStatus());
        student.setCreateTime(new Date());

        boolean insert = studentService.insert(student);
        return insert ? ResponseVO.ok("添加成功") : ResponseVO.error("添加失败");

    }

    /**
     * 多选框删除
     *
     * @param students
     * @return
     */
    @PostMapping("deletes")
    @ResponseBody
    public ResponseVO deletes(@RequestBody List<Student> students) {
        for (Student student : students) {

            deletePic(student.getStudentId());

        }

        int deletes = studentService.deletes(students);
        return deletes > 0 ? ResponseVO.ok("删除成功") : ResponseVO.error("出错了");
    }


    /**
     * 编辑
     *
     * @param student
     * @return
     */
    @PostMapping("edit")
    @ResponseBody
    public ResponseVO edit(@RequestBody Student student) {
        boolean b = studentService.updateDynamic(student);
        return b ? ResponseVO.ok("success") : ResponseVO.error("编辑error");
    }

    /**
     * 单个删除根据studentId
     *
     * @param studentId
     * @return
     */
    @GetMapping("deleteone")
    @ResponseBody
    public ResponseVO delete(Integer studentId) {

        deletePic(studentId);
        boolean delete = studentService.delete(studentId);
        return delete ? ResponseVO.ok("success") : ResponseVO.error("删除error");
    }

    private void deletePic(Integer studentId) {
        Student student = studentService.selectByStudentId(studentId);

        String picture = student.getPicture();
        if (StringUtils.isBlank(picture)) {
            return;
        }
        String s = picture.replaceFirst(ImgPrefix.IMG_PREFIX, url);
        pictureController.deleteDiskPict(s);
    }

    /**
     * 单个插入数据或者更新
     *
     * @param student
     * @return
     */
    @PostMapping("insert")
    @ResponseBody
    public ResponseVO inserts(@RequestBody Student student) {
        log.info("student:[{}]", student);

        if (student.getStudentId() != null) {
            student.setUpdateTime(new Date());
            studentService.updateDynamic(student);
        } else {
            student.setCreateTime(new Date());
            boolean insert = studentService.insert(student);
        }


        return ResponseVO.ok("提交成功");
    }


    /**
     * 获取学生信息根据studentId
     *
     * @param studentId
     * @return
     */
    @PostMapping("getOne")
    @ResponseBody
    public ResponseVO getOne(Integer studentId) {
        log.info("studentId:[{}]", studentId);
        Student student = studentService.selectByStudentId(studentId);
        return ResponseVO.ok(student);

    }

    /**
     * 翻页记忆选中只限单选
     *
     * @param ids
     * @return
     */
    @PostMapping("deletearr")
    @ResponseBody
    public ResponseVO deletesByStringArr(String ids) {
        if (StringUtils.isBlank(ids)) {
            return ResponseVO.error("无数据");
        } else {
            String[] split = ids.split(",");
            studentService.deleteByStringArr(split);
            log.info(ids);
            return ResponseVO.ok("删除成功");
        }

    }


}
